﻿using System;
using System.Collections.Generic;
using System.Text;
using WatiN.Core.Interfaces;
using WatiN.Core.Logging;
using WatiN.Core.HtmlUnit;
using WatiN.Core.UtilityClasses;
using com.gargoylesoftware.htmlunit;
using WatiN.Core.HtmlUnit.Handlers;

namespace WatiN.Core
{
	public class HU : Browser
	{
		HUAlertHandler alertHandler = new HUAlertHandler();
		HUConfirmHandler confirmHandler = new HUConfirmHandler();
		HUPromptHandler promptHandler = new HUPromptHandler();
		HUStatusHandler statusHandler = new HUStatusHandler();
		HUIncorrectnessListener incorrectnessListener = new HUIncorrectnessListener();
		HUWebWindowListener webWindowListener = new HUWebWindowListener();

		HUBrowser browser;
		
		public HU()
		{
			browser = new HUBrowser(this);
			RegisterHandlers();
		}

		public HU(string url)
		{
			browser = new HUBrowser(this);
			RegisterHandlers();

			browser.Navigate(new Uri(url));
		}

		public HU(string url, string proxyHost, int proxyPort)
		{
			ProxyConfig pc = new ProxyConfig(proxyHost, proxyPort);
			browser = new HUBrowser(this, pc);
			RegisterHandlers();

			browser.Navigate(new Uri(url));
		}

		public HU(string proxyHost, int proxyPort)
		{
			ProxyConfig pc = new ProxyConfig(proxyHost, proxyPort);

			browser = new HUBrowser(this, pc);
			RegisterHandlers();
		}

		public HU(string proxyHost, int proxyPort, string username, string password, HUBrowserType browserType)
		{
			browser = new HUBrowser(this, TranslateBrowserVersion(browserType), proxyHost, proxyPort, username, password);
			RegisterHandlers();
		}

		public HU(HUBrowserType browserType)
		{
			browser = new HUBrowser(this, TranslateBrowserVersion(browserType));
			RegisterHandlers();
		}

		public HU(string proxyHost, int proxyPort, HUBrowserType browserType)
		{
			ProxyConfig pc = new ProxyConfig(proxyHost, proxyPort);
			browser = new HUBrowser(this, pc, TranslateBrowserVersion(browserType));

			RegisterHandlers();
		}

		private void RegisterHandlers()
		{
			browser.Client.setAlertHandler(alertHandler);
			browser.Client.setConfirmHandler(confirmHandler);
			browser.Client.setPromptHandler(promptHandler);
			browser.Client.setStatusHandler(statusHandler);
			browser.Client.setIncorrectnessListener(incorrectnessListener);

			webWindowListener.PageChanged += new HUWebWindowListener.PageChangedDelegate(webWindowListener_PageChanged);
			browser.Client.addWebWindowListener(webWindowListener);

			NicelyResynchronizingAjaxController nrac = new NicelyResynchronizingAjaxController();
			browser.Client.setAjaxController(nrac);
								
			
		}

		void webWindowListener_PageChanged(com.gargoylesoftware.htmlunit.html.HtmlPage newPage, com.gargoylesoftware.htmlunit.html.HtmlPage oldPage, string frame)
		{
			//if (newPage != null && frame.Equals(""))
			//	browser.CurrentPage = newPage;
		}

		protected override void navigateTo(Uri url)
		{
			browser.Navigate(url);
		}

		public override IntPtr hWnd
		{
			get { return IntPtr.Zero; }
		}

		public override INativeDocument NativeDocument
		{
			get
			{
				return new HUDocument(browser.CurrentPage, browser);				
			}
		}

		public override INativeDocument OnGetNativeDocument()
		{
			return new HUDocument(browser.CurrentPage, browser);
		}

		public override INativeBrowser NativeBrowser
		{
			get { return browser; }
		}

		public override void WaitForComplete()
		{
			browser.CurrentPage.getEnclosingWindow().getThreadManager().joinAll(50000);
		}

		public override void WaitForComplete(int waitForCompleteTimeOut)
		{
			browser.CurrentPage.getEnclosingWindow().getThreadManager().joinAll(50000);
		}

		public void ToggleJavascript(bool enabled)
		{
			browser.JavascriptEnabled = enabled;
		}

		private BrowserVersion TranslateBrowserVersion(HUBrowserType type)
		{
			BrowserVersion result = BrowserVersion.FIREFOX_3;

			switch (type)
			{
				case HUBrowserType.Firefox:
					result = BrowserVersion.FIREFOX_3;
					break;
				case HUBrowserType.InternetExplorer:
					result = BrowserVersion.INTERNET_EXPLORER_7;
					break;
			}

			return result;
		}

		
	}
}
